python:可迭代对象,迭代器,生成器函数,生成器的解析举例代码说明 您所在的位置:网站首页 Python 生成器函数 python:可迭代对象,迭代器,生成器函数,生成器的解析举例代码说明

python:可迭代对象,迭代器,生成器函数,生成器的解析举例代码说明

2023-08-17 04:22| 来源: 网络整理| 查看: 265

0 总述

主要介绍可迭代对象(iterable)、迭代器(iterator)、生成器(generator)。

迭代是python最强大的功能之一,是访问集合元素的一种方法。

迭代的概念

迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。

1 可迭代对象(iterable) 1.1 定义介绍 在python中, 某对象实现__iter__()方法或者实现__getitem__()方法而且其参数从0开始索引,那么该对象就是可迭代对象。定义可迭代对象时必须实现__iter__()方法或者__getitem__()方法。使用iter()方法将可迭代对象变成迭代器。通俗的说就是可以用for循环的对象都是可迭代对象。例如:list、dict、tuple、set、string。其实都是序列,所以说任何序列都是可迭代的对象, 其原因在于他们至少都会实现__getittem__()方法。(序列都可以通过索引获取元素)是一种通俗的叫法,并不是指某种具体的数据类型。迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。 1.2 对可迭代对象进行迭代操作的具体过程 调用可迭代对象的__iter__()方法,返回一个迭代器对象调用迭代器的__next__()方法返回每一次迭代的内容,直到迭代完成后,抛出stopiteration异常。可迭代对象之所以能迭代,是因为实现了__iter__()方法。当使用for循环时候,解释器会检查对象是否有__iter__ ()方法,有的话就是调用它来获取一个迭代器。所以没有__iter__ ()方法但实现了__getitem__ (),解释器会创建一个迭代器,尝试从0开始按顺序遍历元素。如果尝试失败,Python便会抛出TypeError错误。

image-20210828165700701

image-20210828175958653

所以说虽然字符串、列表、元组、字典、集合等均不是迭代器,但是他们可以在for中进行循环的原因是他们是可迭代对象,在进行迭代操作中会有__iter__()返回对应的迭代器,本质上就是对调用__iter__()后得到的迭代器通过不断使用next()函数实现的,例如:下面举例说明:

list_data = [1,2,3] list_iterator = iter(list_data) str_data = "1,2,3" str_iterator = iter(str_data) tuple_data = (1,2,3) tuple_iterator = iter(tuple_data) dict_data = {"1":1,"2":2,"3":3} dict_iterator = iter(dict_data) print(type(list_iterator)) print(type(str_iterator)) print(type(tuple_iterator)) print(type(dict_iterator))

使用while循环模拟for...in的作用

list1 = [1, 2, 3, 4, 5] iterator = iter(list1) # 使用iter()转换为迭代器 iterator = list1.__iter__() # 使用__iter__()转换为迭代器 while True: try: print(iterator.__next__(), end = " ") # 使用__next__()函数进行迭代 # print(next(iterator)) # 使用next()函数进行迭代 except StopIteration as e: break

image-20210828172458971

1.3 创建一个可迭代对象 class Vector(object): def __init__(self,components): self.components = list(components) def __iter__(self): return iter(self.components) V1 = Vector([1,2,3]) for i in V1: print(i)

image-20210827121428305

上面的例子中实现了 __iter__()方法,解释器可以从类对象中重复地取出元素并打印。

1.4 判断是否是可迭代对象

如果要检查某一个对象是否为可迭代对象,其实可以使用isinstance()函数,该函数用于判断对象是否为某一类型。

# Python 3.9之前 from collections import Iterable print(isinstance([1,2,3],Iterable)) # Python 3.9以后 from collections.abc import Iterable print(isinstance([1,2,3],Iterable)) # 使用typing 库 from typing import Iterable print(isinstance([1,2,3], Iterable))

举例说明:

class Vector(object): def __init__(self,components): self.components = list(components) def __iter__(self): return iter(self.components) vector_data = Vector([1,2,3]) vector_iterator = iter(vector_data) list_data = [1,2,3] list_iterator = iter(list_data) from typing import Iterable from typing import Iterator print("使用typing库Iterable和Iterator") print("vector_data :是否为可迭代对象{},是否为迭代器{}".format(isinstance(vector_data, Iterable),isinstance(vector_data, Iterator))) print("vector_iterator:是否为可迭代对象{},是否为迭代器{}".format(isinstance(vector_iterator, Iterable),isinstance(vector_iterator, Iterator))) print("list_data :是否为可迭代对象{},是否为迭代器{}".format(isinstance(list_data, Iterable),isinstance(list_data, Iterator))) print("list_iterator :是否为可迭代对象{},是否为迭代器{}".format(isinstance(list_iterator, Iterable),isinstance(list_iterator, Iterator))) from collections.abc import Iterable from collections.abc import Iterator print("使用collections.abc库Iterable和Iterator") print("vector_data :是否为可迭代对象{},是否为迭代器{}".format(isinstance(vector_data, Iterable),isinstance(vector_data, Iterator))) print("vector_iterator:是否为可迭代对象{},是否为迭代器{}".format(isinstance(vector_iterator, Iterable),isinstance(vector_iterator, Iterator))) print("list_data :是否为可迭代对象{},是否为迭代器{}".format(isinstance(list_data, Iterable),isinstance(list_data, Iterator))) print("list_iterator :是否为可迭代对象{},是否为迭代器{}".format(isinstance(list_iterator, Iterable),isinstance(list_iterator, Iterator)))

image-20210828164903483

注意点

如果可迭代对象只是实现了__getitem__() 的话,abc.Iterable是不考虑该方法的,这便导致了isinstance()判断不准确。更准确的方法应该是尝试调用iter()函数,如果该对象不可迭代,就会抛出TypeError的错误。

from collections.abc import Iterable class Vector(object): def __init__(self,components): self.components = list(components) def __getitem__(self,index): return self.components[index] V1 = Vector([1,2,3]) print(isinstance(V1,Iterable)) V1 = iter(V1) print(isinstance(V1,Iterable))

image-20210828180246483

2 迭代器(iterator) 迭代器可以记住遍历对象的位置。其内部有一个状态用于记录迭代所在的位置,以便下次迭代时候能取出正确的元素迭代器有两个基本方法iter()、next()。使用iter()方法将可迭代对象变成迭代器。使用next()方法返回下一个值。定义迭代器,必须实现__iter__()和__next__()方法。(Python 2 里是需要类内有next()方法)从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。字符串,列表或元组对象都可用于创建迭代器。迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器。例如:字符串、字典、元组、集合等。迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。 2.1 创建一个迭代器

next()方法调用到末尾的时候会跳出StopIteration,for循环等就是在此时终止循环的

list_data = [1,2,3] interator_data = iter(list_data) print(interator_data) print(type(interator_data)) print(next(interator_data)) print(next(interator_data)) print(next(interator_data)) print(next(interator_data))

image-20210828111821630

2.2 判断是否是迭代器

可以参考1.4

2.3 使用for进行迭代器的使用 list_data = [1,2,3] interator_data = iter(list_data) print(interator_data) for i in interator_data: print(i,end=" ")

image-20210828112017978

2.4 使用next()进行迭代器的使用 import sys interator_data = iter([1,2,3]) while True: try: print (next(interator_data), end=" ") except StopIteration: sys.exit()

image-20210828112257185

2.5 可迭代对象与迭代器的区别

迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器。例如:字符串、字典、元组、集合等。

迭代器可以使用next()方法,但是可迭代对象不一定可以使用next()方法。

一般可以使用iter()方法将可迭代对象变成迭代器。

list_data = [1,2,3] interator_data = iter(list_data) print(interator_data) print(type(interator_data)) print(next(interator_data)) print(type(list_data)) print(next(list_data))

image-20210828113928444

2.5 创建一个迭代器

定义一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

类中成员函数__iter__() 在外部对类的示例化变量调用iter()方法的时候会被调用,主要功能是实现返回一个特殊的迭代器对象(一般就是自己),(一般也会再次或者在__init__()中设置迭代器的七点)。

类内成员函数__next__()在外部对类的示例化变量调用next()方法的时候会被调用,会返回迭代器中下一个需要被迭代出的值,一般中间应该有StopIteration异常,对迭代的完成进行标识控制。

创建一个返回数字的迭代器,初始值为 1,逐步递增 1:

class My_interator: def __iter__(self): self.start_number = 1 return self def __next__(self): if self.start_number


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有